import fnmatch
import serial
import time
import datetime
import re
import sys
import subprocess
import threading

# USR参数设置
Debug_Port = "COM4"  # 215模块debug口，用于debug操作
# 默认参数
Baud_rate = 115200
DEBUG_LOG = ""
STATISTIC_LOG = ""
VM_LOG = ""
# 执行systemctl start compensator指令等待时间/S
time_ExecuteStart = 5


# 发送端口指令
def at_write(command, port_opened):
    port_command = command.encode("UTF-8")
    port_opened.write(port_command)


# 读取端口返回
def at_read(at_port_opened, logfile=""):
    rec_str = ""
    while True:
        time.sleep(5)

        lenth = at_port_opened.inWaiting()
        if lenth > 0:
            rec_str = at_port_opened.read(size=lenth)
            try:
                rec_str = re.sub("\\x1b.*?m", "", rec_str.decode("UTF-8"), 0, re.I)
                if logfile != "":
                    with open(logfile, "a", encoding="utf-8") as file_object:
                        file_object.write(
                            "[" + str(datetime.datetime.now()) + "]" + str(rec_str)
                        )
                return rec_str
            except:
                return ""
        else:
            break


def creatLogFile():
    global DEBUG_LOG
    DEBUG_LOG = "{}_Debuglog.txt".format(
        time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
    )


# 检查端口连接状态
def check_DEBUG_singnal():
    global debug_serial
    try:
        debug_serial = serial.Serial(Debug_Port, Baud_rate)
    except:
        print("debug口连接失败，请检查端口")
        sys.exit()
    return debug_serial


def login(debug_serial, logfile):
    # at_write('cd \r\n', debug_serial)
    while True:
        res = at_read(debug_serial, logfile)
        print("---------{}----------".format(res))
        if "login:" in res:
            at_write("root\r\n", debug_serial)
            time.sleep(1)
            at_write(
                "fmOlFugB5vYQqM2ugwE-EJAFaBkPiU0DBLxwW1adToai8qKA5NXYKAMotNHNn5XMjH4pzieLzh9e-JsLfTEo1zgBozMiSc-x3CnO8luM0aSNFun1NgbgBOKkDf-S1tfC\r\n",
                debug_serial,
            )
        elif "~ #" in res:
            print("登录成功")
            break


def check_gnss_lock():
    at_write("gnss --start\r\n", debug_serial)

    while True:
        gnss_res = at_read(debug_serial, DEBUG_LOG)

        # 匹配 GNRMC 语句，检查是否包含 'A'
        if re.search(r"\$GNRMC,[^,]*,A,", gnss_res):
            print("定位成功")
            with open(DEBUG_LOG, "a", encoding="utf-8") as file_object:
                file_object.write(f"[{str(datetime.datetime.now())}] 定位成功\n")

            # 发送 Ctrl+C (chr(3)) 退出 gnss 命令
            at_write(chr(3), debug_serial)
            print("发送 Ctrl+C 退出 gnss 命令")
            with open(DEBUG_LOG, "a", encoding="utf-8") as file_object:
                file_object.write(
                    f"[{str(datetime.datetime.now())}] 发送 Ctrl+C 退出 gnss 命令\n"
                )

            return True

        print("定位未成功，继续检测...")
        with open(DEBUG_LOG, "a", encoding="utf-8") as file_object:
            file_object.write(
                f"[{str(datetime.datetime.now())}] 定位未成功，继续检测...\n"
            )

    print("定位失败")
    with open(DEBUG_LOG, "a", encoding="utf-8") as file_object:
        file_object.write(f"[{str(datetime.datetime.now())}] 定位失败\n")
    return False


def create_and_log_vm_status():
    # 创建日志文件
    timestamp = time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
    log_file = f"VM_LOG_{timestamp}.log"
    with open(log_file, "w", encoding="utf-8") as file:
        file.write(" VM.LOG日志开始记录...\n")

    def write_log(log):
        # 写入日志信息
        with open(log_file, "a", encoding="utf-8") as file_object:
            now_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            file_object.write(f"{now_time}\r\n{log}\r\n")

    def send_adb_command(command):
        # 发送 ADB 命令并返回输出结果
        try:
            result = subprocess.run(
                ["adb", "shell", command], capture_output=True, text=True
            )
            return result.stdout
        except Exception as e:
            return str(e)

    # 执行命令并写入日志
    commands = [
        "pgrep -af engine-service.*DRE | awk '{print $1}' | xargs -i -t sh -c 'grep Vm /proc/{}/status'",
        "pgrep -af location_hal_daemon | awk '{print $1}' | xargs -i -t sh -c 'grep Vm /proc/{}/status'",
        "pgrep -af slim_daemon | awk '{print $1}' | xargs -i -t sh -c 'grep Vm /proc/{}/status'",
    ]

    for command in commands:
        result = send_adb_command(command)
        write_log(f"{command} 命令执行结果：\r\n{result}")


# 新增一个周期性运行的函数，每分钟执行一次
def periodic_task():
    while True:
        print("执行周期性查询任务")
        create_and_log_vm_status()
        # 每分钟执行一次
        time.sleep(60)


def main():
    creatLogFile()
    # 启动周期性任务线程
    periodic_thread = threading.Thread(target=periodic_task)
    periodic_thread.daemon = True  # 将线程设置为守护线程，主线程结束时自动退出
    periodic_thread.start()
    check_DEBUG_singnal()
    # login(debug_serial, DEBUG_LOG)

    if not check_gnss_lock():
        print("无法获取定位，停止脚本。")
        sys.exit()

    kill_count = 0  # 初始化Kill计数器

    while True:
        # 检查特定进程
        at_write("ps | grep gps\r\n", debug_serial)
        process_res = at_read(debug_serial, DEBUG_LOG)

        # 查找特定的进程
        found_ppe = "engine-service PPE libppe_core.so" in process_res
        found_dre_int = "engine-service DRE-INT libloc_epDr.so" in process_res

        # 如果两个进程都没有找到，执行 systemctl restart loc_launcher 并重新检查
        if not found_ppe and not found_dre_int:
            print("没有目标进程，重启 loc_launcher 服务...")
            at_write("systemctl restart loc_launcher\r\n", debug_serial)
            at_read(debug_serial, DEBUG_LOG)  # 等待服务启动

            # 再次检查进程
            at_write("ps | grep gps\r\n", debug_serial)
            process_res = at_read(debug_serial, DEBUG_LOG)

            # 更新进程检查结果
            found_ppe = "engine-service PPE libppe_core.so" in process_res
            found_dre_int = "engine-service DRE-INT libloc_epDr.so" in process_res

            # 如果重启服务后依然没有目标进程，退出脚本
            if not found_ppe and not found_dre_int:
                print("重启服务后仍无目标进程，退出脚本。")
                break

        # 如果找到进程，则进行杀死操作
        if found_ppe:
            kill_count += 1  # 增加Kill计数器
            print(f"第 {kill_count} 次杀掉进程: engine-service PPE libppe_core.so")
            with open(DEBUG_LOG, "a", encoding="utf-8") as file_object:
                file_object.write(
                    f"[{str(datetime.datetime.now())}] 第 {kill_count} 次杀掉进程: engine-service PPE libppe_core.so\n"
                )
            at_write(
                "kill $(ps | grep \"engine-service PPE libppe_core.so\" | awk '{print $1}')\r\n",
                debug_serial,
            )
            at_read(debug_serial, DEBUG_LOG)

        if found_dre_int:
            kill_count += 1  # 增加Kill计数器
            print(f"第 {kill_count} 次杀掉进程: engine-service DRE-INT libloc_epDr.so")
            with open(DEBUG_LOG, "a", encoding="utf-8") as file_object:
                file_object.write(
                    f"[{str(datetime.datetime.now())}] 第 {kill_count} 次杀掉进程: engine-service DRE-INT libloc_epDr.so\n"
                )
            at_write(
                "kill $(ps | grep \"engine-service DRE-INT libloc_epDr.so\" | awk '{print $1}')\r\n",
                debug_serial,
            )
            at_read(debug_serial, DEBUG_LOG)

        # 等待一小段时间后再次检查
        time.sleep(time_ExecuteStart)


if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("程序中断。")
